#ifndef __SCHED_LOTTERY__
#define __SCHED_LOTTERY__

#include <map>
#include "basesched.h"
#include <utility>

#include <sstream> // PARA ANALISIS
#include <string> // PARA ANALISIS

class SchedLottery : public SchedBase {
        public:
                SchedLottery(std::vector<int> argn);				// argn[0] = #cores | argn[1] = quantum | argn[2] = semilla
   			    ~SchedLottery();
                virtual void load(int pid);							// Por cada tarea NUEVA que llega al sistema se llama a load.
                virtual void unblock(int pid);						// Cuando una tarea deja de estar bloqueada, se llama a unblock.
                virtual int tick(int cpu, const enum Motivo m);
       
        private:	

        		struct lottery_information
        		{
        			int cpu;
        			int tick;
        			int winner;
        			int numberOfVictories;
        			int numberOfLotteries;

        			std::string toString(){
        				std::stringstream ss;
                        ss << "CPU " << cpu << ";TICK " << tick << ";WIN " << winner << ";VIC " << numberOfVictories << ";LOT " << numberOfLotteries <<"\n";
						std::string s = ss.str();
						return s;
        			}
        			
        			std::string toStringEstadistica()
        			{
						std::stringstream ss;
                        ss << ";WIN " << winner << ";VIC " << numberOfVictories << ";LOT " << numberOfLotteries <<"\n";
						std::string s = ss.str();
						return s;
					}
        			
        		}; // PARA ANALISIS

        		int next(int cpu, Motivo m);
        		int checkWinner(int winning_ticket);
				void write(char* filename, struct lottery_information lottery_info, bool logGlobal); //PARA ANALISIS
                void resetTicket(std::map<int, int> * m, int key);       // Given a map with tickets and the pid. This function sets the ticket of pid to base_ticket and modifies the value of tickets_distributed
                int handleTick(int cpu);
                void handleBlock(int cpu);
                void handleExit(int cpu);
                void switchTaskTick(int running_pid, int nextPid);
                void switchTask(int nextPid);


				int base_tickets;									// Este entero representa la cantidad de tickets iniciales que recibe una tarea.
				int tickets_distributed;							// Este entero representa la sumatoria de todos los tickets repartidos hasta el momento de todas las tareas que aún no terminaron.
				int quantum;										// Este entero representa el quantum de cada core.

				std::vector<int> quantum_left;						      // Cada posicion del vector tiene el quantum restante de cada core. La longitud del vector es igual a la cantidad de cores.
				std::map<int, int> activeTasks; 					    // Todas las tareas ACTIVAS con su ultimo ticket. (map<tarea, ticket>)
				std::map<int, int> blockedTasks; 					   // Todas las tareas BLOQUEADAS con su ultimo ticket. (map<tarea, ticket>)
                std::vector<int> current_tick_by_cpu;                    // PARA ANALISIS (poner abajo d todo)
                std::vector<struct lottery_information> infoTasks;				//De tamaño #tareas
                int lotteryNumber;
};

#endif
